#include "Computer.h"

//对于静态数据成员的初始化而言，不能放在初始化表达式中，要放在
//全局静态的位置。特别的，对于头文件与实现文件的形式，我们要
//放在实现文件中进行初始化，否则就会报多重定义的错误

float Computer::_totalPrice = 0;//总价

Computer::Computer(const char *brand, float price)
: _brand(new char[strlen(brand) + 1]())
, _price(price)
/* , _totalPrice(0)//error */
{
    cout << "Computer(const char *, float)" << endl;
    /* _brand = new char[strlen(brand) + 1]();//申请空间，防止越界 */
    strcpy(_brand, brand);
    _totalPrice += _price;
}

#if 0
//编译器默认生成的拷贝构造函数不行
Computer::Computer(const Computer &rhs)
: _brand(rhs._brand)//浅拷贝
, _price(rhs._price)
{
    cout << "Computer(const Computer &)" << endl;
}
#endif

//自定义拷贝构造函数
//Q1:拷贝构造函数参数中的引用符号可以去掉吗？
//
//Q2:拷贝构造函数参数中的const关键字可以去掉吗？
//
Computer::Computer(const Computer &rhs)
: _brand(new char[strlen(rhs._brand) + 1]())//先申请空间,深拷贝
, _price(rhs._price)
{
    cout << "Computer(const Computer &)" << endl;//拷贝
    strcpy(_brand, rhs._brand);
}

#if 0
Computer &Computer::operator=(const Computer &rhs)
{
    cout << "Computer &operator=(const Computer &)" << endl;
    _brand = rhs._brand;//浅拷贝
    _price = rhs._price;

    return *this;
}
#endif

//com1 = com1
Computer &Computer::operator=(const Computer &rhs)
{
    cout << "Computer &operator=(const Computer &)" << endl;
    /* if(不是自己赋值给自己) */
    /* if(*this != rhs) */
    if(this != &rhs)//1、自复制,防止自己赋值给自己
    {
        delete [] _brand;//2、释放左操作数，解决内存泄漏
        _brand = nullptr;

        //3、深拷贝，防止内存越界
        _brand = new char[strlen(rhs._brand) + 1]();
        strcpy(_brand, rhs._brand);
        _price = rhs._price;
    }

    return *this;//4、返回*this
}

void Computer::setBrand(const char *brand)
{
    strcpy(_brand, brand);
}

void Computer::setPrice(float price)
{
    _price = price;
}

void Computer::print(/* Computer * const this */)
{
    cout << "void print()" << endl;
    /* this->_price = 5000;//ok */
    cout << "_brand = " << _brand << endl
         << "_price = " << _price << endl;

    /* this->_totalPrice;//ok */
    /* this->printTotalPrice();//ok */
}

//具有只读特性（对数据成员只能读不能改）
void Computer::print(/* const Computer * const this */) const
{
    cout << "void print() const" << endl;
    /* this = nullptr;//error */
    /* this->_price = 5000;//error */
    cout << "_brand = " << _brand << endl
         << "_price = " << _price << endl;

}

//静态成员函数的特点？
//1、对于静态成员函数而言，其第一个参数的位置没有隐含的this
//2、静态的成员函数不能访问非静态的数据成员与非静态的成员函数
//3、非静态的成员函数可以访问静态的数据成员与静态的成员函数
//4、如果静态的成员函数想访问非静态的数据成员或者成员函数，可以
//使用函数传参的形式，或者在静态成员函数体中创建对象
//5、静态成员函数可以使用类名与作用域限定符的形式进行调用
//（独特之处，其他的非静态成员函数不能这么调用）
void Computer::printTotalPrice()
{
    /* Computer com("dhhd", 888); */
    /* com.print(); */
    /* printf("this : %p\n", this);//error */
    /* _price = 5000;//error */
    /* this->print(); */
    cout << "_totalPrice = " << _totalPrice << endl;
}

#if 0
void func(const Computer &pt)
{
    pt.print();
}
#endif

//析构函数的清理操作有时候需要手动清理
Computer::~Computer()
{
    cout << "~Computer()" << endl;
    _totalPrice -= _price;
    if(_brand)//_brand != nullptr
    {
        /* cout << "delete " << endl; */
        delete [] _brand;
        _brand = nullptr;
    }
}
